package classfile

const (
	Code_String               string = "Code"
	ConstantValue_String      string = "ConstantValue"
	Deprecated_String         string = "Deprecated"
	Exceptions_String         string = "Exceptions"
	LineNumberTable_String    string = "LineNumberTable"
	LocalVariableTable_String string = "LocalVariableTable"
	SourceFile_String         string = "SourceFile"
	Synthetic_String          string = "Synthetic"
)

type AttributeInfo interface {
	readInfo(reader *ClassReader)
}

func readAttributes(count uint16, reader *ClassReader, cp ConstantPool) []AttributeInfo {
	attributes := make([]AttributeInfo, count)
	for i := range attributes {
		attributes[i] = readAttribute(reader, cp)
	}
	return attributes
}

func readAttribute(reader *ClassReader, cp ConstantPool) AttributeInfo {
	attrIndex := reader.readUint16()
	attrLen := reader.readUint32()

	attrInfo := newAttributeInfo(attrIndex, attrLen, cp)
	attrInfo.readInfo(reader)
	return attrInfo
}

func newAttributeInfo(attribute_name_index uint16, attribute_length uint32, cp ConstantPool) AttributeInfo {
	attributeName := cp.getUtf8(attribute_name_index)
	switch attributeName {
	case Code_String:
		return &CodeAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length,cp: cp} //ok
	case ConstantValue_String:
		return &ConstantValueAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case Deprecated_String:
		return &DeprecatedAttribute{MarkerAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length}} //ok
	case Exceptions_String:
		return &ExceptionsAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case LineNumberTable_String:
		return &LineNumberTableAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case LocalVariableTable_String:
		return &LocalVariableTableAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case SourceFile_String:
		return &SourceFileAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case Synthetic_String:
		return &SyntheticAttribute{MarkerAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length}}
	default:
		return &UnparsedAttribute{attributeName, attribute_length, nil}
	}

}
